package online.zhangwenzhe.common.security;

import online.zhangwenzhe.common.CustomProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Service
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    Authenticator authenticator;

    @Autowired
    CustomProperties customProperties;

    private static final int BEARER_HEAD_LENGTH = 7;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {

        // 没有配置默认不鉴权
        if (customProperties == null ||
                customProperties.getOauth2() == null ||
                !customProperties.getOauth2().isEnable()) {
            return true;
        }


        // 获取Token对应的用户信息
        String authorizationHeader = httpServletRequest.getHeader("Authorization");

        UserDetails userDetails = null;

        if (!StringUtils.isEmpty(authorizationHeader) && authorizationHeader.length() > BEARER_HEAD_LENGTH) {
            String token = authorizationHeader.substring(BEARER_HEAD_LENGTH);
            userDetails = authenticator.verifyToken(token);
        }

        if (userDetails != null) {
            //todo: 目前只保存了用户ID，其他信息需要进一步添加
            httpServletRequest.setAttribute("user", userDetails.getUserId());
            UserContext.setUserDetails(userDetails);
        }

        String uri = httpServletRequest.getRequestURI();
        String method = httpServletRequest.getMethod();
        // 允许匿名访问则不再进行后续鉴权
        if (customProperties.getOauth2().isAllowAnonymous() && authenticator.allowAnonymous(uri, method)) {
            return true;
        }

        // Token存在问题
        if (userDetails == null) {
            httpServletResponse.setStatus(401);
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("text/html;charset=utf-8");
            httpServletResponse.getWriter().write("token无效");
            return false;
        }

        // 鉴权
        if (!authenticator.verifyAuthority(userDetails.getUserId(), uri, method)) {
            httpServletResponse.setStatus(403);
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("text/html;charset=utf-8");
            httpServletResponse.getWriter().write("无权访问");
            return false;
        }

        return true;
    }
}
